<template>
  <el-dialog v-model="dialogVisible" title="分类管理" width="500px" @close="onClose">
    <el-row>
      <el-col :span="24">
        <el-tree
          :data="treeData"
          :props="treeProps"
          node-key="id"
          default-expand-all
          highlight-current
          draggable
          @node-drop="onDrop"
          style="margin-bottom: 16px;"
        >
          <template #default="{ node, data }">
            <span>{{ data.name }}</span>
            <el-button type="primary" link size="small" @click.stop="editCategory(data)">编辑</el-button>
            <el-button type="danger" link size="small" @click.stop="deleteCategory(data)">删除</el-button>
            <el-button type="success" link size="small" @click.stop="addCategory(data)">添加子类</el-button>
          </template>
        </el-tree>
      </el-col>
    </el-row>
    <el-dialog v-model="formVisible" :title="formTitle" width="400px" append-to-body>
      <el-form :model="form" :rules="rules" ref="formRef" label-width="80px">
        <el-form-item label="分类名称" prop="name">
          <el-input v-model="form.name" placeholder="请输入分类名称" />
        </el-form-item>
        <el-form-item label="上级分类">
          <el-select v-model="form.parentId" placeholder="无（顶级分类）" clearable style="width:100%">
            <el-option :value="null" label="无（顶级分类）" />
            <el-option v-for="cat in flatCategories" :key="cat.id" :value="cat.id" :label="cat.name" />
          </el-select>
        </el-form-item>
        <el-form-item label="描述">
          <el-input v-model="form.description" type="textarea" rows="2" placeholder="请输入描述" />
        </el-form-item>
        <el-form-item label="排序">
          <el-input-number v-model="form.order" :min="1" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="formVisible = false">取消</el-button>
        <el-button type="primary" @click="onSubmit">保存</el-button>
      </template>
    </el-dialog>
    <template #footer>
      <el-button @click="onClose">关闭</el-button>
      <el-button type="primary" @click="addCategory()">添加分类</el-button>
    </template>
  </el-dialog>
</template>

<script lang="ts" setup>
import { ref, computed, watch, nextTick } from 'vue'
import { ElMessageBox, ElMessage } from 'element-plus'

const props = defineProps<{ visible: boolean; categories: any[] }>()
const emit = defineEmits(['update:visible', 'update:categories'])

const dialogVisible = computed({
  get: () => props.visible,
  set: (val: boolean) => emit('update:visible', val)
})
const treeProps = { label: 'name', children: 'children' }
const formRef = ref()
const formVisible = ref(false)
const formTitle = ref('')
const form = ref({ id: null, name: '', parentId: null, description: '', order: 1 })

const treeData = computed(() => buildTree(props.categories))
const flatCategories = computed(() => props.categories)

function buildTree(list: any[]) {
  const map = new Map()
  list.forEach(item => map.set(item.id, { ...item, children: [] }))
  const tree: any[] = []
  map.forEach(item => {
    if (item.parentId && map.has(item.parentId)) {
      map.get(item.parentId).children.push(item)
    } else {
      tree.push(item)
    }
  })
  // 排序
  tree.forEach(sortChildren)
  tree.sort((a, b) => (a.order || 1) - (b.order || 1))
  return tree
}
function sortChildren(node: any) {
  if (node.children && node.children.length) {
    node.children.forEach(sortChildren)
    node.children.sort((a: any, b: any) => (a.order || 1) - (b.order || 1))
  }
}

function addCategory(parent?: any) {
  formTitle.value = parent ? '添加子分类' : '添加分类'
  form.value = { id: null, name: '', parentId: parent ? parent.id : null, description: '', order: 1 }
  formVisible.value = true
  nextTick(() => formRef.value?.clearValidate())
}
function editCategory(data: any) {
  formTitle.value = '编辑分类'
  form.value = { ...data }
  formVisible.value = true
  nextTick(() => formRef.value?.clearValidate())
}
function deleteCategory(data: any) {
  ElMessageBox.confirm('确定要删除该分类及其所有子分类吗？', '提示', { type: 'warning' })
    .then(() => {
      const ids = collectIds(data)
      const newList = props.categories.filter(cat => !ids.includes(cat.id))
      emit('update:categories', newList)
      ElMessage.success('删除成功')
    })
    .catch(() => {})
}
function collectIds(node: any): any[] {
  let ids = [node.id]
  if (node.children && node.children.length) {
    node.children.forEach((child: any) => {
      ids = ids.concat(collectIds(child))
    })
  }
  return ids
}
const rules = {
  name: [{ required: true, message: '请输入分类名称', trigger: 'blur' }],
}
function onSubmit() {
  formRef.value.validate((valid: boolean) => {
    if (valid) {
      let newList = [...props.categories]
      if (form.value.id) {
        // 编辑
        newList = newList.map(cat => (cat.id === form.value.id ? { ...form.value } : cat))
      } else {
        // 新增
        const newId = newList.length ? Math.max(...newList.map(c => c.id)) + 1 : 1
        newList.push({ ...form.value, id: newId })
      }
      emit('update:categories', newList)
      formVisible.value = false
      ElMessage.success('保存成功')
    }
  })
}
function onDrop(draggingNode: any, dropNode: any, type: string) {
  // 仅支持同级排序
  if (type === 'inner') return
  const dragId = draggingNode.data.id
  const dropId = dropNode.data.id
  let newList = [...props.categories]
  const dragItem = newList.find(c => c.id === dragId)
  const dropItem = newList.find(c => c.id === dropId)
  if (dragItem && dropItem) {
    dragItem.order = dropItem.order + (type === 'after' ? 1 : -1)
    // 重新排序
    newList = newList.map(c => ({ ...c }))
  }
  emit('update:categories', newList)
}
function onClose() {
  emit('update:visible', false)
}
</script> 